/**
* Funciones auxiliares para el manejo de la estructura asociada a la
* metainformacion de una aplicacion
*
* @author Carlos Rodriguez Dominguez
*/

#ifndef _MIAPPLICATION_H_
#define _MIAPPLICATION_H_

#include "collaboration.h"

namespace MIApplication {

	/**
	* Obtiene la posicion de un rol en el vector de roles de una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return Posicion del rol o -1 si no existe
	*/
	int getRole(const Collaboration::MIApplication& app, 
				const ::std::string& role);
	
	/**
	* Obtiene la posicion de un usuario en el vector de usuarios de una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return Posicion del usuario o -1 si no existe
	*/
	int getUser(const Collaboration::MIApplication& app, 
				const ::std::string& user);
	
	/**
	* Obtiene la posicion de un componente en el vector de componentes de una aplicacion
	*
	* @param app Aplicacion
	* @param comp Componente
	* @return Posicion del componente o -1 si no existe
	*/
	int getComponent(const Collaboration::MIApplication& app, 
					const ::std::string& comp);

	/**
	* Agrega un rol a una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return True si se pudo agregar o False en caso contrario
	*/
	bool addRole(Collaboration::MIApplication& app, 
				Collaboration::MIRole& role);
	
	/**
	* Elimina un rol de una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return True si se pudo eliminar o False en caso contrario
	*/
	bool removeRole(Collaboration::MIApplication& app, 
					const ::std::string& role);
	
	/**
	* Agrega un usuario a una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return True si se pudo agregar o False en caso contrario
	*/
	bool addUser(Collaboration::MIApplication& app, 
				Collaboration::MIUser& user);
	
	/**
	* Elimina un usuario de una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return True si se pudo eliminar o False en caso contrario
	*/
	bool removeUser(Collaboration::MIApplication& app, 
					const ::std::string& user);
	
	/**
	* Actualiza la marca de tiempo de un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return True si se actualizo la marca de tiempo o False en caso contrario
	*/
	bool updateUserTime(Collaboration::MIApplication& app, 
						const ::std::string& user);
	
	/**
	* Pone un usuario como conectado
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return Rol del usuario o NULL si ocurrio algun error
	*/
	::std::string setConnectedUser(Collaboration::MIApplication& app, 
									const ::std::string& user);
	
	/**
	* Desconecta un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	*/
	void setDisconnectedUser(Collaboration::MIApplication& app, 
							const ::std::string& user);
	
	/**
	* Agrega un componente a un aplicacion
	*
	* @param app Aplicacion
	* @param comp Componente
	*/
	void addComponent(Collaboration::MIApplication& app, 
					Collaboration::MIComponent& comp);
	
	/**
	* Agrega un nivel de permisos para un componente y un rol. Si el componente no existe, lo CREA
	*
	* @param app aplicacion
	* @param role Rol
	* @param comp Componente
	* @param permissions Permisos
	*/
	void addRoleComponentPermissions(Collaboration::MIApplication& app, 
									const ::std::string& role, 
									const ::std::string& comp, 
									::Ice::Int permissions);
										
	/**
	* Agrega un nivel de permisos para un componente y un usuario. Si el componente no existe, lo CREA
	*
	* @param app aplicacion
	* @param user Usuario
	* @param comp Componente
	* @param permissions Permisos
	*/
	void addUserComponentPermissions(Collaboration::MIApplication& app, 
									const ::std::string& user, 
									const ::std::string& comp, 
									::Ice::Int permissions);
										
	/**
	* Obtiene los permisos de un rol sobre un componente
	*
	* @param app Aplicacion
	* @param role Rol
	* @param comp Componente
	* @return Nivel de permisos del rol sobre el componente o -1 si hubo algun error
	*/
	::Ice::Int roleComponentPermissions(Collaboration::MIApplication& app, 
										const ::std::string& role, 
										const ::std::string& comp);
	
	/**
	* Comprueba si un rol existe para una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return True si existe o False en caso contrario
	*/
	bool existsRole(const Collaboration::MIApplication& app, 
					const ::std::string& role);
	
	/**
	* Comprueba si un usuario existe para una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return True si existe o False en caso contrario
	*/
	bool existsUser(const Collaboration::MIApplication& app, 
					const ::std::string& user);
	
	/**
	* Comprueba si un componente existe para una aplicacion
	*
	* @param app Aplicacion
	* @param comp Componente
	* @return True si existe o False en caso contrario
	*/
	bool existsComponent(const Collaboration::MIApplication& app, 
						const ::std::string& comp);
	
	/**
	* Asigna el rol actual de un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param newrole Nuevo rol actual del usuario
	* @return True si el rol pudo cambiarse o False en caso contrario
	*/
	bool setActualUserRole(Collaboration::MIApplication& app, 
							const ::std::string& user, 
							const ::std::string& newrole);
	
	/**
	* Agrega un rol permitido para un usuario
	* 
	* @param app Aplicacion
	* @param user Usuario
	* @param newrole Rol
	* @return True si pudo agregarse el rol al usuario
	*/
	bool addUserAllowedRole(Collaboration::MIApplication& app, 
							const ::std::string& user, 
							const ::std::string& newrole);
	
	/**
	* Elimina un rol permitido para un usuario
	* 
	* @param app Aplicacion
	* @param user Usuario
	* @param role Rol
	* @return True si pudo eliminarse el rol del usuario
	*/
	bool removeUserAllowedRole(Collaboration::MIApplication& app, 
								const ::std::string& user, 
								const ::std::string& role);
	
	/**
	* Obtiene la metainformacion de los usuarios no actualizados
	*
	* @param app Aplicacion
	* @return Lista con la metainformacion de los usuarios no actualizados
	*/
	Collaboration::ListOfUsers getNonUpdatedUsers(const Collaboration::MIApplication& app);
	
	/**
	* Obtiene una lista con los nombres de los usuarios de un rol determinado
	*
	* @param app Aplicacion
	* @param role Rol
	* @return Lista con los nombres de los usuarios de un rol
	*/
	Collaboration::ListOfStrings getRoleUsers(const Collaboration::MIApplication& app, 
												const ::std::string& role);
	
	/**
	* Obtiene una matriz con los nombres de los usuarios conectados y sus roles actuales
	*
	* @param app Aplicacion
	* @return Matriz con los nombres de los usuarios conectados y sus roles actuales.
	*         En la primera fila de la matriz estan los usuarios y en la segunda estan los roles
	*/
	Collaboration::ListOfUsersAndRoles getConnectedUsers(const Collaboration::MIApplication& app);
	
	/**
	* Obtiene la metainformacion completa de los usuarios conectados
	*
	* @param app Aplicacion
	* @return Lista con la metainformacion de los usuarios conectados
	*/
	Collaboration::ListOfUsers getConnectedUsersInfo(const Collaboration::MIApplication& app);
	
	/**
	* Obtiene el nombre del rol actual de un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return Nombre del rol actual
	*/
	::std::string getActualUserRole(Collaboration::MIApplication& app, 
									const ::std::string& user);
	
	/**
	* Obtiene los permisos de un usuario sobre un componente
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param comp Componente
	* @return Nivel de permisos del usuario sobre el componente o -1 si hubo algun error
	*/
	::Ice::Int userComponentPermissions(Collaboration::MIApplication& app, 
										const ::std::string& user, 
										const ::std::string& comp);
	
	/**
	* Asigna el nivel de permisos para un componente existente
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param comp Componente
	* @param permissions Permisos
	* @return True si se pudo asignar el nivel de permisos o False en caso contrario
	*/
 	bool setUserComponentPermissions(Collaboration::MIApplication& app, 
									const ::std::string& user, 
									const ::std::string& comp, 
									::Ice::Int permissions);
													
	/**
	* Asigna el nivel de permisos para un componente existente
	*
	* @param app Aplicacion
	* @param role Rol
	* @param comp Componente
	* @param permissions Permisos
	* @return True si se pudo asignar el nivel de permisos o False en caso contrario
	*/
	bool setRoleComponentPermissions(Collaboration::MIApplication& app, 
									const ::std::string& role, 
									const ::std::string& comp, 
									::Ice::Int permissions);
	
}

#endif
